package de.gwtprime.client.widgets.trading;

import java.util.List;

import com.google.common.collect.Lists;
import com.google.gwt.cell.client.ActionCell;
import com.google.gwt.cell.client.Cell.Context;
import com.google.gwt.core.client.GWT;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
import com.google.gwt.user.cellview.client.SimplePager;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SingleSelectionModel;

import de.gwtprime.client.ClientFactory;
import de.gwtprime.client.util.GWTUtils;
import de.gwtprime.client.widgets.helper.InfoPopup;
import de.gwtprime.client.widgets.trading.popup.OrderPaymentTriggeredPopup;
import de.gwtprime.client.widgets.trading.popup.OrderPopupStorno;
import de.gwtprime.client.widgets.trading.popup.PaymentPopup;
import de.gwtprime.client.widgets.trading.popup.TradeConfirmationPopup;
import de.gwtprime.shared.requestFactory.OrderProxy;
import de.gwtprime.shared.requestFactory.OrderProxy.OrderState;
import de.gwtprime.shared.requestFactory.OrderProxy.OrderType;

public class TradingTable extends Composite {

	public enum BuySellTable{
		BUY, 
		SELL,
		OWN_ORDERS
	}

	@UiField
	CellTable<OrderProxy> table;

	@UiField
	SimplePager pager;

	@UiField Label title;

	final  ListDataProvider<OrderProxy> newdataProvider = new ListDataProvider<OrderProxy>();
	List<OrderProxy> list2 = newdataProvider.getList();

	private BuySellTable buySellTable;


	private static TradingTableUiBinder uiBinder = GWT
			.create(TradingTableUiBinder.class);

	interface TradingTableUiBinder extends UiBinder<Widget, TradingTable> {
	}

	public TradingTable(final ClientFactory clientFactory, List<OrderProxy> orders, final BuySellTable buySellTable) {
		initWidget(uiBinder.createAndBindUi(this));


		this.title.setText(buySellTable==BuySellTable.BUY ? "Kauf Anfragen" : "Verkaufs Anfragen");

		this.buySellTable = buySellTable;

		if(buySellTable==BuySellTable.OWN_ORDERS){

			this.title.setText("Deine offenen Positionen");
		}

		updateOrders(orders);

		// Create a CellTable.
		table.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
		table.setEmptyTableWidget(new Label(GWTUtils.I18n.noTradeTableEntries()));
		newdataProvider.addDataDisplay(table);

		//SelectionCell categoryCell = new SelectionCell(null);

		// Add a text column to show the address.
		TextColumn<OrderProxy> addressColumn = new TextColumn<OrderProxy>() {
			@Override
			public String getValue(OrderProxy object) {
				return  String.valueOf(object.getPrice());
			}
		};
		table.addColumn(addressColumn, "Preis");

		// Add a text column to show the name.
		TextColumn<OrderProxy> amountColumn = new TextColumn<OrderProxy>() {
			@Override
			public String getValue(OrderProxy object) {
				return String.valueOf(object.getAmount());
			}
		};
		table.addColumn(amountColumn, "LTC");


		TextColumn<OrderProxy> euroColumn = new TextColumn<OrderProxy>() {
			@Override
			public String getValue(OrderProxy object) {
				if(object.getAmount()==null || object.getPrice()==null)
					return "-";
				return String.valueOf(object.getAmount()*object.getPrice());
			}
		};
		table.addColumn(euroColumn, "Euro");

		// Add a selection model to handle user selection.
		final SingleSelectionModel<OrderProxy> selectionModel = new SingleSelectionModel<OrderProxy>();
		table.setSelectionModel(selectionModel);
		selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
			public void onSelectionChange(SelectionChangeEvent event) {
				//	        Contact selected = selectionModel.getSelectedObject();
				//	        if (selected != null) {
				//	          Window.alert("You selected: " + selected.name);
				//	        }
			}
		});




		class DetailsButton extends Column<OrderProxy, OrderProxy>
		{
			public DetailsButton()
			{

				super(new ActionCell<OrderProxy>("Details", new ActionCell.Delegate<OrderProxy>() {
					@Override
					public void execute(OrderProxy order)
					{
						if(clientFactory.getUser()==null){
							new InfoPopup(GWTUtils.I18n.notLoggedIn()).center();;
							return;
						}
						//	                	new TradeConfirmationPopup2(clientFactory, order).center();



						if(order.getState()==OrderState.STORNIERT){

							new InfoPopup("Diese order wurde storniert").center();
						}else if(order.getState()==OrderState.OPEN){
							new OrderPopupStorno(clientFactory, order).center();
						}              	


						else if(order.getState()==OrderState.WAITING_FOR_PAYMENT){
							if(isSell(clientFactory, order))
								new InfoPopup("Warte auf Zahlung").center();
							else 
								new PaymentPopup(clientFactory, order).center();
						}else if(order.getState()==OrderState.PAYMENT_TRIGGERED){
							if(isSell(clientFactory, order))
								new OrderPaymentTriggeredPopup(clientFactory, order).center();
							else 
								new InfoPopup("Zahlung angewiesen - Warte auf Bestätigung des Verkäufers").center();
						}else if(order.getState()==OrderState.COMPLETE){
							new InfoPopup("Transaktion abgeschlossen").center();
						}


						//Window.alert(String.valueOf(order.getAmount()));
						/**
						 *Here you go. You got a reference to an object in a row that delete was clicked. Put your "delete" code here
						 */
					}


				}));
			}

			@Override
			public OrderProxy getValue(OrderProxy object)
			{
				return object;
			}


		};

		class BuySellColumn extends Column<OrderProxy, OrderProxy>
		{
			public BuySellColumn()
			{

				super(new ActionCell<OrderProxy>((buySellTable == BuySellTable.BUY) ? "Verkaufen" : "Kaufen", new ActionCell.Delegate<OrderProxy>() {
					@Override
					public void execute(OrderProxy order)
					{
						if(clientFactory.getUser()==null){
							new InfoPopup(GWTUtils.I18n.notLoggedIn()).center();;
							return;
						}

						// For Buy orders -> Check if potential seller has sufficient funds
						if(order.getType()==OrderType.BUY){
							if(clientFactory.getUser().getBalanceBitcoin() < order.getAmount()){
								new InfoPopup("Du hast nicht genug LTC").center();;
								return;
							}
						}
						new TradeConfirmationPopup(clientFactory, order).center();

					}
				}));
				
				
			}

			@Override
			public OrderProxy getValue(OrderProxy object)
			{
				return object;
			}
			@Override
			public void render(Context context, OrderProxy object,
					SafeHtmlBuilder sb) {
				
				// Don't render the buy / sell button for the creator of the order -> don't allow the creator
				// to buy / sell his own orders
				if(object.getUserName()!=null && clientFactory.getUser()!=null && clientFactory.getUser().getEmail()!=null &&
						!object.getUserName().startsWith(clientFactory.getUser().getEmail())){
					super.render(context, object, sb);
				}else{
					// Just show a centered "-" instead of the buy / sell button for the owner
					sb.append(new SafeHtmlBuilder().appendHtmlConstant("<div style='text-align:center'>-</div>").toSafeHtml());
				}
			}
		};

		if(buySellTable==BuySellTable.BUY || buySellTable == BuySellTable.SELL){
			
			
			//Column<OrderProxy, ActionCell> editColumn = (new IdentityColumn(editCell));
			table.addColumn(new BuySellColumn(), "Handel");

		}

		if(buySellTable==BuySellTable.OWN_ORDERS){
			TextColumn<OrderProxy> stateColumn = new TextColumn<OrderProxy>() {
				@Override
				public String getValue(OrderProxy object) {
					if(object.getState()==OrderState.STORNIERT){
						return "Storniert";
					}

					if(object.getState()==OrderState.OPEN){
						return "Offen";
					}
					else if(object.getState()==OrderState.WAITING_FOR_PAYMENT){

						if(isSell(clientFactory, object))  
							return "Auf Zahlung warten";
						else
							return "Zahlung muss ausgeführt";
					}else if(object.getState()==OrderState.PAYMENT_TRIGGERED){

						if(isSell(clientFactory, object))  
							return "Zahlung angewiesen";
						else
							return "Zahlung angewiesen";
					}else{
						return String.valueOf(object.getState());

					}

				}
			};
			table.addColumn(stateColumn, "Status");


			TextColumn<OrderProxy> buySellColumn = new TextColumn<OrderProxy>() {
				@Override
				public String getValue(OrderProxy order) {

					// boolean isSell = clientFactory.getUser().equals(order.getSeller());

					//			    	  if(order.getTypeInt()==0){
					//			    		  return "Kauf";
					//			    	  }else if(order.getTypeInt()==0){
					//			    		  return "Verkauf";
					//			    	  }else{
					//			    		  return "-";
					//			    	  }
					if(isSell(clientFactory, order)){
						return "Verkauf";
					}else{
						return "Kauf";
					}

				}
			};
			table.addColumn(buySellColumn, "Kauf/Verkauf");

			table.addColumn(new DetailsButton(), "Details");

		}

		// Set the total row count. This isn't strictly necessary, but it affects
		// paging calculations, so its good habit to keep the row count up to date.
		table.setRowCount(orders.size(), true);


		pager.setDisplay(table);


		addStyleName("center");



	}

	public void updateOrders(List<OrderProxy> orders) {

		list2.clear();

		pager.setVisible(orders.size()>15);

		if(buySellTable==BuySellTable.BUY){
			orders = Lists.reverse(orders); 
		}

		for (OrderProxy day : orders) {
			list2.add(day);
		}
	}

	private boolean isSell(final ClientFactory clientFactory,
			OrderProxy order) {
		boolean isSell = clientFactory.getUser().equals(order.getSeller());
		return isSell;
	}



}
